Basic Acoustic Features
When we analyze audio signals, we usually adopt the method of short-term analysis since most audio signals are more or less stable within a short period of time, say 20 ms or so. When we do frame blocking, there may be some soverlap between neighboring frames to capture subtle change in the audio signals. Note that each frame is the basic unit for our analysis. Within each frame, we can observe the three most distinct acoustic features, as follows.

    * Volume: This feature represents the loudness of the audio signal, which is correlated to the amplitude of the signals. Sometimes it is also referred to as energy or intensity of audio signals.
    * Pitch: This feature represents the vibration rate of audio signals, which can be represented by the fundamental frequency, or equivalently, the reciprocal of the fundamental period of voiced audio signals.
    * Timbre: This feature represents the meaningful content (such as a vowel in English) of audio signals, which is characterized by the waveform within a fundamental period of voice signals. 
Take human voices as an example, then the above three acoustic features will correlates to some physical quantities:

    * Volume: It correlates to the compression of your lungs. A large volume of audio signals corresponds to a large compression.
    * Pitch: It correlates to the vibration frequency of your vocal cord. A high pitch corresponds to a high vibration frequency.
    * Timbre: It correlates to the positions and shapes of your lips and tongue. Different timbres corresponds to different positions and shapes of your lips and tongue. 

It should be noted that these acoustic features mostly corresponds to human's "perception" and therefore cannot be represented exactly by mathematical formula or quantities. However, we still try to "quantitify" these features for further computer-based analysis in the hope that the used formula or quantities can emulate human's perception as closely as possible. 


The basic approach to the extraction of audio acoustic features can be summarized as follows:

   1. Perform frame blocking such that a strem of audio signals is converted to a set of frames. The time duration of each frame is about 20~30 ms. If the frame duration is too big, we cannot catch the time-varying characteristics of the audio signals. On the other hand, if the frame duration is too small, then we cannot extract valid acoustic features. In general, a frame should be contains several fundamental periods of the given audio signals. Usually the frame size (in terms of sample points) is equal to the powers of 2 (such as 256, 512, 1024 ,etc) such that it is suitable for fast fourier transform.
   2. If we want to reduce the difference between neighboring frames, we can allow overlap between them. Usually the overlap is 1/2 to 2/3 of the original frame. The more overlap, the more computation is needed.
   3. Assuming the audio signals within a frame is stationary, we can extract acoustic features such as zero crossing rates, volume, pitch, MFCC, LPC, etc.
   4. We can perform endpoint detection based on zero crossing rate and volume, and keep non-silence frames for further analysis. 

When we are performing the above procedures, there are several terminologies that are used often:

    * Frame size: The sampling points within each frame
    * Frame overlap: The sampling points of the overlap between consecutive frames
    * Frame step (or hop size): This is equal to the frame size minus the overlap.
    * Frame rate: The number of frames per second, which is equal to the sample frequency divided by the frame step. 

%Hint
%Note that these terminologies are not unified. Some papers use frame step to indicate hop size or frame rate instead. You should be cautious when reading papers with these terms.

For instance, if we have a stream of audio signals with sample frequency fs=16000, and a frame duration of 25 ms, overlap of 15 ms, then

    * Frame size = fs*25/1000 = 400 (sample points)。
    * Frame overlap = fs*15/1000 = 240 (sample points)。
    * Frame step (or hop size) = 400-240 = 160 (sample points)。
    * Frame rate = fs/160 = 100 frames/sec。 


3-3 Human Voice Production

    The procedure from human voice production to voice recognition involves the following steps:

       1. Rapid open and close of your vocal cords (or glottis) to generate the vibration in air flow.
       2. Resonance of the pharyngeal cavity, nasal cavity, and oral cavity.
       3. The vibration of air.
       4. The vibration of the ear drum (or tympanum).
       5. The reception of the inner ear.
       6. The recognition by the brain. 


Due to the pressure of the glottis and the air pushed from the lungs, the vocal cords can open and close very quickly, which generates vibrations in the air. The vibration is modulated by the resonances of pharyngeal/nasal/oral cavities, forming different timbre of your voices. In other words:

    * The vibration frequency of the vocal cords determines the pitch of the voices.
    * The positions/shapes of your lips, tongue, and nose determine the timbre.
    * The compression from your lungs determine the loudness of the voice

We can conceive the production of human voices as a source-filter model where the source is the airflow caused by the vocal cords, and the filter includes the pharyngeal/nasal/oral cavities. The following figure shows the representative spectrum for each stage: 

FIGURA human voice 2
We can also use the following block diagram to represent the source-filter model of human voice production: 
source filter model

In general, a regular vibration of the glottis will generate quasi-periodic voiced sounds. On the other hand, if the source is irregular airflow, then we will have unvoiced sounds.

SECCiÓn MATLAB for Audio Signal Processing tutorial para leer, grabar, audio
Se explican las funciones de Matlab que pueden ser utilizadas para el procesamiento de señales de audio.
Cómo leer archivos .wav
Cómo ejecutar las señales de audio
Cómo grabar desde el micrófono
cómo guardar archivos .wav


Una extensión de archivo común es .wav para señales de audio. Este formato puede leerse desde cualquier sistema operativo. El comando de MATLAB para leer estos archivos es \textverbatim{wavread}. Dejo más claro este paso en el siguiente ejemplo.
Aquí se lee el archivo wav "paula_orden_alto.wav" y luego muestra la forma de onda
%generar ejemplo

\verbatim [y, fs]=wavread('paula_orden_alto.wav'); 
sound(y, fs); % Playback de los datos, en y tengo la longitud en segundos del archivo
time=(1:length(y))/fs; % Vector de tiempo 
plot(time, y); % Dibujo la forma de onda
\verbatim


En este caso "fs" es la frecuencia de muestreo de (11025 - X?). Esto indica que hay X muestras por segundo cuando se grabó esta muestra. El vector "y" es un vector columna que contiene las muestras de la señal de voz. La utilización de \textxverbatim {sound(y, fs)} es para ejecutar la señal de audio leída desde el archivo wav. El vetor "time"  es un vector de tiempo en el que cada elemento corresponde al tiempo de cada punto muestreado. Es por eso que se puede dibujar "y" vs. "time" para mostrar directamente la forma de onda.


La mayoría de las señales de audio son digitalizadas con una resolución de 8 o 16. Si quisieramos saber la resolución de el archivo .wav podemos pedirle al comando "wavread" más argumentos de salida:

[y, fs, nbits]=wavread('paula_orden_alto.wav');

Es más, si quisiéramos conocer la duración de un stream de seañales de audio, podríamos usar directamente "length(y)/fs".

Ejemplo
\begin{verbatim} {
fileName='paula_orden_izquierda.wav'; al crear una variable para el nombre de archivo, podemos utilizar el script .m para cualquier archivo.
[y, fs, nbits]=wavread(fileName); 
fprintf('Informacion del archivo de sonido "%s":\n', fileName); 
fprintf('Duration = %g segundos \n', length(y)/fs); fprintf('Frecuencia de muestreo = %g muestras/segundo\n', fs); fprintf('Resolucion = %g bits/muestra\n', nbits);

Mensaje de Salida

Informacion del archivo de sonido "paula_orden_izquierda.wav":
Duracion = 1.45134 segundos 
Frecuencia de muestreo = 11025 muestras/segundo
Resolucion = 8 bits/muestra 
}
\end{verbatim}

No hay que dejar de observar que todas las señales de audio son representadas entre -1 y 1. Sin embargo, cada punto está representado por un entero de 8 bits.
Debe tenerse en cuenta que:
   1. Si un archivo de audio tiene una resolución de 8 bits, luego cada punto muestreado se guarda como un entero sin signo cuyo valor está dentro del rango 0 y 255 ($= 2^{8}-1$).
   2. Si un archivo de audio tiene una resolución de 16 bits, luego cada punto se guardará con un valor dentro del rango  -32768 (= 2^16/2) y 32767 (= 2^16/2-1). 

Como la mayor parte de las variables en MATLAB son del tipo "double", entonces todos los untos se convierten en úmeros floating-point entre -1 and 1 para una manipulación más sencilla. Si deseamos recuperar los valores enteros originales de la señal de audio, debemos realizar:


   1. Para resolución de 8-bits multiplicamos "y" 128 y luego sumamos 128.
   2. Para resolución de 16-bits multiplicamos "y" por 32768 y luego sumamos 32768.

\section Playback de las señales de audio
Una vez que se obtiene la señal de audio deseada, para extraer datos es necesario modificar su intensidad, cambiar la frecuencia de muestreo entre otras características.
Una vez procesadas, es necesario reproducirlas para inspección aural (auditiva). 

El comando básico para reproducir señales de audio es "wavplay". Las siguientes líneas cargan señales de audio desde el archivo "vocales.mat" y las reproducen inmediatamente.

\begin{verbatim}
{load vocales.mat \% Carga las señales almacenadas en vocales.mat
wavplay(y, Fs); \% Reproduce las señales

}
\end{verbatim}

Dado que el volumen de la reproducción está determinado por la amplitud de las señales de audio, se puede cambiar la amplitud en orden de cambiar el volumen de la siguiente manera.

\begin verbaim
{[y, fs]=wavread('paula_orden_izquierda.wav');
wavplay(1*y, fs, 'sync'); \% Reproduce con la amplitud original
wavplay(3*y, fs, 'sync'); \% Reproduce con una amplitud triplicada
wavplay(5*y, fs, 'sync'); \% Reproduce con 5 veces la amplitud original
}
\end{verbatim}

El argumento de entrada 'sync' hará que las señales se reproduzcan de manera sincrónica, es decir, que la reproducción no comenzará hasta que la previa no haya finalizado.


A pesar de haber aumentado la amplitud por un factor de 5, la intensidad percivida por nuestros oídos no es por ese factor. La percepción del volumen no es linealmente proporcional a la amplitud. De hecho es proporcional al logaritmo de la amplitud.

Si se cambia la frecuencia de muestreo durante la reproducción, afectará el tiempo de duración así como también el tono percibido. Si se aumenta la frecuencia de muestreo se escuchará un sonido corto de tono alto (high pitch). 

\begin{verbatim} {
[y, fs]=wavread('paula_orden_derecha.wav');
wavplay(y, 1.0*fs, 'sync'); \% Reproduce a la velocidad original
wavplay(y, 1.2*fs, 'sync'); \% Reprodce a 1.2 veces la velocidad original
wavplay(y, 1.5*fs, 'sync'); \% Reprodce a 1.5 veces la velocidad original
wavplay(y, 2.0*fs, 'sync'); \% Reprodce a 2 veces la velocidad original
}
\end{verbatim}

Si se baja la fs, entonces se escuchará un sonid más largo y de tono bajo, como el mugido de una vaca.

\begin{verbatim}
{
[y, fs]=wavread('paula_orden_derecha.wav'); 
wavplay(y, 1.0*fs, 'sync'); \% Reproduce a la velocidad original
wavplay(y, 0.9*fs, 'sync'); \% Reprodce a 0.9 veces la velocidad original 
wavplay(y, 0.8*fs, 'sync'); \% Reprodce a 0.8 veces la velocidad original
wavplay(y, 0.6*fs, 'sync'); \% Reprodce a 0.6 veces la velocidad original
}
\end{verbatim}

Si invertimos las señales de audio multiplicando por -1, la percepción será exactamente la misma que la original. Esto demuestra que la percepción humana del sonido no se ve afectada por el cambise. Sin embargo si invertimos la señal en el eje del tiempo, el sonido será como el de un idioma extranjero que desconocemos.

\begin{verbatim}
{
[y, fs]=wavread('paula_orden_alto.wav');
wavplay(y, fs, 'sync'); \% Reproduce la señal original
wavplay(-y, fs, 'sync');\% Reproduce la señal invertida de arriba a abajo
wavplay(flipud(y), fs, 'sync'); \% Reproduce la señal invertida de izquierda a derecha
}
\end{verbatim}

Cuando se reproduce un strem de audio, MATLAB tiene dos modos de reproducirlo:

   1. Sync: MATLAB detendrá toda otra ejecución de comandos hasta que la reproducción haya finalizado.
   2. Async: MATLAB continuará con la ejecución de comandos mientras la reproducción está en curso. 

\section grabar desde el Micrófono

Para esto se utiliza el comando "wavrecord" para leer las señales de audio directamente desde el micrófono. La
forma del comando es
\begin{verbatim}{ 
y = wavrecord(n, fs);
}
donde "n" es el número de muestras a ser grabadas y "fs" es la frecuencia de muestreo. 

\begin{verbatim}
{fs=16000; \% Frecuencia de muestreo
duration=2; \% duración de la grabación
fprintf('Presione cualquier tecla para comenzar \%g segundos de grabación...', duration); 
pause fprintf('grabando...'); 
y=wavrecord(duration*fs, fs); \% duration*fs es número total de muestras
fprintf('grabación finalizada.\n'); 
fprintf('Presione cualquier tecla pra reproducir grabación...'); 
pause wavplay(y,fs);
}
\end{verbatim}

En este script "duration*fs" es el número de muestras a grabar. Estos puntos se guardan en la variable "y", la cual es un vector de 32000x1. El tipo de dato de "y" es doble y la memoria ocupada por "y" es 256.000 bytes. 

Nota:
Los comandos 'wavplay' y 'wavrecord' son  soportado en la plataforma Microsoft Windows. (fijarse si en MATLAB R2008a UNIX 64 también es así).

Los siguientes son los tipos de datos que se pueden utilizar con el comando 'wavrecord':

\begin {table}
{ccc}{Tipos de dato & Requerimiento de memoria por muestra & Rango de los datos muestreados\\

double	&	8 bytes/muestra	&	Número real $\in$ [-1, 1]\\

single	&	4 bytes/muestra	&	Número real $\in$ [-1, 1]\\

int16 	&	2 bytes/muestra	&	Entero $\in \, \[-32768, 32767\] o \[-2^{(nbits-1)}, 2^{(nbits-1)}-1]$\\

uint8 	&	1 byte/muestra 	&	Entero $\in[0, 255] o [0, 2^{nbits}-1] 
}
\end {table}



\section Guardar archivos de audio

Se pueden escribir archivos de audio en formato .wav usando el comando 'wavwrite'. El formato tiene los siguientes argumentos de entrada:
\begin{verbatim} 
{
wavwrite(y, fs, nbits, waveFile);
}
\end{verbatim}

donde "y" son los datos,"fs" es la frecuencia de muestreo, "nbits" es la resolución de bits y "waveFile" es el archivo que será escrito. El siguiente script muestra cómo grabar una orden.

\begin{verbatim}
fs=11025; 
duration=2; % duración de grabado
waveFile='paula_orden_alto.wav'; 
fprintf('Presione cualquier tecla para comenzar %g segundos de grabación...', duration);
pause fprintf('Grabando...');
y=wavrecord(duration*fs, fs); 
fprintf('Grabación finalizada.\n');
fprintf('Presione cualquier tecla para guardar los datos de sonido en %s...', waveFile);
pause 
nbits=8; % Resolución. tipo uint8
wavwrite(y, fs, nbits, waveFile);
fprintf('Escritura de datos finalizada %s\n', waveFile);
fprintf('Presione cualquier tecla para reproducir %s...\n', waveFile);
dos(['Comienzo ', waveFile]); % comienza la aplicación para archivo .wav
\end{verbatim}

Se puede ver en este ejemplo que el tipo de dato grabado con 'wavwrite' es 'uint8' y cuando se llame a la aplicación para la reproducción del archivo .wav la variable "y" debería ser del tipo doble y estar en el rango [-1, 1]; es necesario hacer conversiones si los datos grabados están en otro tipo de dato como 'single', 'int16', or 'uint8'.

Tabla para conversión
\begin{table}
{cc}
{
Tipo de dato de "y"	&	Cómo convertirlo en 'double' $\in [-1, 1]$\\

double			&	No se necesita conversión\\

single			&	y = double(y);\\

int16 			&	y = double(y)/32768;\\

uint8 			&	y = (double(y)-128)/128;

\end {table}

Se pueden grabar en otro tipo de archivos de audio, como '.au', cuyo comando correspondiente es "auwrite".

Nota:
Si se quiere realizar únicamente el procesamiento de señales de audio en MATLAB, entonces se pueden guardar los datos en formato '.mat' utilizando el comando "save". Para cargarlos luego se usa el comando "load" direcamente.


\section Volumen

"Sound loudness is a subjective term describing the strength of the ear's perception of a sound. It is intimately related to sound intensity but can by no means be considered identical to intensity. The sound intensity must be factored by the ear's sensitivity to the particular frequencies contained in the sound. This is the kind of information contained in equal loudness curves for the human ear"
%Extraído de http://hyperphysics.phy-astr.gsu.edu/Hbase/sound/loud.html



La sonoridad (loudness) de una señal de audio es una de las características más  del hombre. En general, existen avarios términos para describir la sonoridad de estas señales, incluyendo volumen, intensidad y energía. Utilizaré el término volumen por ser muy conocido y para evitar algunas confusiones de terminología.
El volumen es una característica acústica básica correlacionada a la amplitud de cada muestra dentro de un determinado frame. Básicamente hay dos métodos para calcular el volumen de cada frame: 

1.La suma de las muestras absolutas de cada frame:
$volumen = \sum{i}^{n} |s_{i}|$
donde $s_{i}$ es la i-ésima muestra dentro del frame, y n es el tamaño de frame o ventana. Este método requeire solamente operaciones de enteros.
2.10 por el logaritmo en base 10 de la suma de los cuadrados de los puntos de muestra:
$volumen = 10*log(\sum_{i=1:n} s_{i}^{2})$

Este método requiere más cálculo de floating-point, pero está más o menos linealmente correlacionado con nuestra percepción de la sonoridad de las señales acústicas. La unidad usada para esta cantidad es el decibel.

Algunas características del volumen son:

\begin{itemiza}

\item Para grabar en una oficina/laboratorio o departamento utilizando un micrófono unidireccional, el volumen de los sonidos armónicos es mayor que aquel de los no armónicos, y el de estos últimos es más grande que el ruido de fondo.

\item El volumen es altamente influenciado por la configuración del micrófono, particularmente por la ganancia del micrófono.

\item El volumen es usado frecuentemente para detección de punto final (endpoint detection), método que trata de  encontrar la región de actividad más significativa (cuando hay voz)


\item Antes de calcular el voluemn, es aconsejable que se corrija el cero de la ventana (offset) (el valor promedio de la ventana debe ser restado de cada muestra) con el fin de evitar DC-bias debdido a defectos y ruidos propios del hardware.

\end {itemize}


Ejemplo
\begin{verbatim}
waveFile='paula_orden_subir.wav';
frameSize=256;
overlap=128; %solapamiento
[y, fs, nbits]=wavReadInt(waveFile);
fprintf('Largo de %s es %g seg.\n', waveFile, length(y)/fs);
frameMat=buffer(y, frameSize, overlap);
frameNum=size(frameMat, 2);
volume1=zeros(frameNum, 1);
volume2=zeros(frameNum, 1);
for i=1:frameNum frame=frameMat(:,i);
	frame=frame-mean(frame); % corrección de cero
	volume1(i)=sum(abs(frame)); % método 1
	volume2(i)=10*log10(sum(frame.^2)); % método 2
end
	time=(1:length(y))/fs; 
	frameTime=((0:frameNum-1)*(frameSize-overlap)+0.5*frameSize)/fs;
	subplot(3,1,1); plot(time, y);
	ylabel(waveFile);
	subplot(3,1,2); plot(frameTime, volume1, '.-');
	ylabel('Volumen (Suma Absoluta)');
	subplot(3,1,3); plot(frameTime, volume2, '.-'); ylabel('Volumen (dB)');
	xlabel('Tiempo (seg)')
\end {verbatim}

La función wavReadInt() que convierte todas las muestars a valores enteros está disponible en Audio Processing Toolbox.

Los dos métodos utilizados son solamente una aproximación de la percepción. Sin embargo, el volumen (loudness) se basa en nuestra percepción y puede haber una diferencia significativa entre "volumen calculado" y "volumen percibido. De hecho, el volumen percibido es muy afectado por la frecuencia, así como también por el timbre de las señales.
Esto es observable en las curvas "Equal Loudness Contour o Curvas Isofónicas" de Fletcher-Munson.

Como se acaba de mencionar, el volumen es influenciado por el timbre. Por ejemplo, si tratamos de pronunciar las vocales utilizando el mismo volumen y luego dibujamos las curvas de volumen, se podrá ver cómo están relacionadas con el timbre o forma/posición de los labios/lengua.

La función frame2volume() que calcula el volumen usando los dos métodos está en Audio Processing Toolbox.


\section {Métodos de Cálculo}

	\subsection{Cruces por Cero - ZCR }

La tasa de cruces por cero (acrónimo en inglés: ZCR. Zero-crossing rate) es otra característica acústica que puede ser calculada de manera sencilla. Es igual al número de cruces por cero de la onda en un cuadro determinado. Las características que presenta son las siguientes:

\begin{itemize}

\item En general, los valores de ZCR de los sonidos no armónicos y del ruido ambiental son más grandes que los de los sonidos armónicos (se observan en estos últimos períodos fundamentales).

\item Es difícil distinguir los sonidos no armónicos del ruido ambiente utilizando solamente este método, dado que tienen valores similares, como se mencionó anteriormente.

\item El cálculo de ZCR a menudo se usa en conjunto con el volumen para la detección de punto final. En particular, se emplea para detectar puntos de comienzo y final de los sonidos no armónicos.

\item Se ha utilizado para la estimación de frecuencia fundamental, pero no es confiable a menos que se realicen otros procedimientos subsecuentes para refinar el cálculo.
 
\end{itemize}

Es necesario tener presentes los siguientes puntos:

\begin{enumerate}

\item Si una muestra está ubicada exactamente en cero (0), surge el el interrogante si se debe contar como cruce por cero. Dependiendo de la respuesta, se tiene dos métodos para calcular ZCR.
\item La mayoría de los cálculos de ZCR se basa en los valores enteros de las señales de audio. Si se quiere realizar la resta de la media, el valor medio debería redondearse al entero más cercano también.
\end{enumerate}

Cálculo de ZCR para el comando 'paula_orden_alto.wav':
zcr_v01.m

\begin{verbatim}

waveFile='paula_orden_alto.wav';
frameSize=256;
overlap=0;
[y, fs, nbits]=wavReadInt(waveFile);
frameMat=buffer(y, frameSize, overlap);
zcr1=sum(frameMat(1:end-1, :).*frameMat(2:end, :)<0); %Método 1
zcr2=sum(frameMat(1:end-1, :).*frameMat(2:end, :)<=0);%Método 2
time=(1:length(y))/fs;
frameNum=size(frameMat, 2);
frameTime=((0:frameNum-1)*(frameSize-overlap)+0.5*frameSize)/fs;
subplot(2,1,1);plot(time, y); ylabel(waveFile); subplot(2,1,2); plot(frameTime, zcr1, '.-', frameTime, zcr2, '.-');
title('Cruces por Cero - ZCR'); xlabel('Tiempo (seg)'); legend('Método 1', 'Método 2');
\end{verbatim}


Al observar la figura de los resultado que se obtienen, se hace evidente que ambas alternativas generan curvas de cruces por cero diferentes. El primer método no cuenta los puntos en cero como si fueran cruces reales, por lo que la tasa es menor. Además los intervalos de silencio tendrán una menor ZCR con el método 1 y un valor mayor con el método 2, considerando que en la región de silencio tenemos muchas muestras de valor 0.\\
Sin embargo, esta observación es válida para frecuencias de muestreo bajas (8kHz en este caso).

A continuación se muestran los resultados para la misma orden/señal con KHz (paula_orden_alto_16khz.wav).

zcr_02.m 
\begin{verbatim}

waveFile='paula_orden_alto_16khz.wav';
frameSize=256;
overlap=0;
[y, fs, nbits]=wavReadInt(waveFile);
frameMat=buffer(y, frameSize, overlap);
zcr1=frame2zcr(frameMat, 1); % Método 1
zcr2=frame2zcr(frameMat, 2); % Método 2 
time=(1:length(y))/fs;
frameNum=size(frameMat, 2);
frameTime=((0:frameNum-1)*(frameSize-overlap)+0.5*frameSize)/fs;
subplot(2,1,1);
plot(time, y);
ylabel(waveFile);
subplot(2,1,2);
plot(frameTime, zcr1, '.-', frameTime, zcr2, '.-');
title('Tasa de Cruces por Cero - ZCR'); xlabel('Tiempo (seg)'); legend('Método 1', 'Método 2');

\end{verbatim}

Las curvas resultantes son similares. Como se había dicho, esta técnica trae inconvenientes para diferenciar los sonidos no armónicos del ruido ambiente.
Una solución que se prueba es realizar un corrimiento a la señal antes de calcular la ZCR por el método 2. 


\begin{verbatim}

waveFile='paula_orden_alto_16khz.wav'; %al parametrizar al archivo de entrada es más fácil probar con distintas señales
frameSize=256;
overlap=0;
[y, fs, nbits]=wavReadInt(waveFile);
frameMat=buffer(y, frameSize, overlap);
volume=frame2volume(frameMat);
[minVolume, index]=min(volume);
shiftAmount=2*max(abs(frameMat(:,index))); % shiftAmount es igual a la muestra máximo absoluta dentro del cuadrp de volumen mín
zcr1=frame2zcr(frameMat, 1);
zcr2=frame2zcr(frameMat, 1, shiftAmount);
subplot(2,1,1); plot(time, y);
ylabel(waveFile);
subplot(2,1,2); plot(frameTime, zcr1, '.-', frameTime, zcr2, '.-');
title('Tasa de Cruces por Cero - Shifted ZCR'); xlabel('Tiempo (seg)'); legend('Método 1 sin corrimiento', 'Método 2 con corrimiento');

\end{verbatim}

En este caso el cantidad que se desplaza la señal para el métdoo 2, es igual a la muestra cuya valor es el máximo absoluto dentro del cuadro de volumen mínimo. De esta forma se reduce dramáticamente el aporte del silencio al valor ZCR, haciendo más fácil la distinción entre sonidos no armónicos y silencio (con ruido ambiental).

	
	\subsection{Determinación de Tono}

De acuerdo con la terminología acústica de ANSI (American National Standards Institute), el tono es el atributo auditivo del sonido según el cual los sonidos pueden ordenarse de graves a agudos.
La altura los ordena de bajos a altos.

En inglés se utiliza pitch o tone indistintamente, el equivalente de pitch en español es altura de un sonido, y difieren con el tono en que uno es la frecuencia fundamental percibida por el oído humano y el otro es la f.f medida con instrumentos físicos.

Debido a diferencias fisiológicas, los rangos de tono para hombres y mujeres son diferentes:

\item El rango en los hombres es 35 ~ 72 semitonos, o 62 ~ 523 Hz.
\item El rango en las mujeres es 45 ~ 83 semitonos, o 110 ~ 1000 Hz.

La fórmula para convertir frecuencia a semitono es la siguiente.

\begin{equation}
semitono = 69 + 12*log_{2}(frac{frequencia}{440})
\end{equation}
Cuando la frecuencia fundamental es 440 Hz, el tono es de 69 semitonos.
  
Sin embargo, no se puede utilizar solamente la característica del TONO para identificar voces masculinas o femeninas. Para esto se suele usar la información de los formantes (timbre en el dominio de la música).

Si se quisiera identificar a la persona que habla se podría incluir en el sistema reconocedor la determinación del tono.

paula_SayMynamePitch.m

\begin{verbatim}

waveFile='paula_SayMynamePitch.wav';
[y, fs, nbits]=wavread(waveFile);
index1=11050; %comienzo del segmento de muestra
frameSize=512;
index2=index1+frameSize-1; %tamaño del segmento de muestra
frame=y(index1:index2);
subplot(2,1,1);
plot(y); grid on title(waveFile);
line(index1*[1 1], [-1 1], 'color', 'r'); %delimitadores
line(index2*[1 1], [-1 1], 'color', 'r');
subplot(2,1,2); plot(frame, '.-');
grid on
point=[75, 477]; %selecciona puntos que cubren la cantidad de períodos fundamentales
line(point, frame(point), 'marker', 'o', 'color', 'red');
periodCount=3; %cantidad de periodos
fp=((point(2)-point(1))/periodCount)/fs; % determina el periodo fundamental
ff=fs/((point(2)-point(1))/periodCount); % determina la frecuencia fundamental
pitch=69+12*log2(ff/440);
fprintf('Período Fundamental = %g segundos\n', fp);
fprintf('Frecuencia Fundamental = %g Hertz\n', ff);
fprintf('Tono = %g semitonos\n', pitch);

\end{verbatim}



	\subsection{Timbre}

Físicamente, el timbre es la cualidad que confieren al sonido los armónicos que acompañan a la frecuencia fundamental. Estos armónicos generan variaciones en la onda sinusoidal base.

Los sonidos simples o tonos puros son ondas sinusoidales de una frecuencia determinada. Sin embargo, en la naturaleza, no existe un sonido puro, libre de armónicos.

El Teorema de Fourier demuestra que cualquier forma de onda periódica puede descomponerse en una serie de ondas (armónicos) cuyas frecuencias son múltiplos de la frecuencia fundamental de la onda original. Así, los armónicos son múltiplos de la frecuencia fundamental, a la que acompañan

El timbre viene determinado por la cantidad e intensidad de estos armónicos. 

En teoría, para señales de audio cuasi-periódicas como la voz, podemos usar la onda dentro de un período fundamental como el timbre de la ventana. Sin embargo, analizar directamente la onda dentro de solo un período fundamental es difícil. Para ello se usa la Transformada Rápida de Fourier (FFT, Fast Fourier Transform) para transformar la señal en el dominio del tiempo al espectro en el dominio de la frecuencia. Esta representación simplemente muestra la intensidad de la onda en cada banda de frecuencias. 
En Matlab se puede utilizar el siguiente demo:

\begin{verbatim}

dspstfft_win32 %(MATLAB 6 and 7) 

\end{verbatim}

		\subsection{End Point Detection}
 
The goal of end-point detection (EPD for short) is to identfy the important part of an audio segment for further processing. Hence EPD is also known as "speech detecton" or "voice activity detection" (VAD for short). EPD plays an important role in audio signal processing and recognition.

Based on the acoustic features used for EPD, we can classify the EPD methods into two types:

   1. Time-domain methods:
         1. Volume: Volume is the most commonly used feature for EPD. However, it is usually hard to have a single universal threshold for EPD. In particular, a single volume threshold for EPD is likely to misclassify unvoiced sounds as silence for audio input from uni-directional microphone.
         2. Volume and ZCR: ZCR can be used in conjunction with volume to identify unvoiced sounds in a more reliable manner, as explained in the next section. 
      The computation load is usually small so these methods can be ported to low-end platform such as micro-controllers.
   2. Frequency-domain methods:
         1. Variance in spectrum: Voiced sounds have more regular amplitude spectra, leading to smaller spectral variances.
         2. Entropy in spectrum: Regular amplitude spectra of voices sounds also generate low entropy, which can be used as a criterion for EPD. 
      These methods usually require more computing power and thus are not portable to low-end platforms. 

Hint
To put it simply, time-domain methods use only the waveform of audio signals for EPD. On the other hand, if we need to use the Fourier transform to analyze the waveforms for EPD, then it is frequency-domain method. More information on spectrum and Fourier transform will be detailed in later chapters.

There are two types of errors in EPD, which cause different effects in speech recognition, as follows.

    * False Rejection: Speech frames are erroneously identified as silence/noise, leading to decreased recognition rates.
    * False Acceptance: Silence/noise frames are erroneously identified as speech frames, which will not cause too much trouble if the recognizer can take short leading/trailing silence into consideration. 

		\subsubsection{EPD Dominio del Tiempo}

We shall introduce several time-domain methods for EPD in this section.

The first method uses volume as the only acoustic feature for EPD. This is the most intuitive method with least computation. We only need to determine a volume threshold and any frame with a volume less than the threshold is regarded as silence. However, how to determine a good volume threshold is not obvious. Besides empirically determining the threshold, the best way is to use a set of labelled training data to find the best value for achieving the minimum error.

In the following example, we shall use four different ways to compute volume thresholds for EPD of the wave file sunday.wav: 

\begin{verbatim}

waveFile='sunday.wav'; [wave, fs, nbits] = wavread(waveFile); frameSize = 256; overlap = 128; wave=wave-mean(wave); % zero-mean substraction frameMat=buffer2(wave, frameSize, overlap); % frame blocking frameNum=size(frameMat, 2); % no. of frames volume=frame2volume(frameMat, 1); % volume volumeTh1=max(volume)*0.1; % volume threshold 1 volumeTh2=median(volume)*0.1; % volume threshold 2 volumeTh3=min(volume)*10; % volume threshold 3 volumeTh4=volume(1)*5; % volume threshold 4 index1 = find(volume>volumeTh1); index2 = find(volume>volumeTh2); index3 = find(volume>volumeTh3); index4 = find(volume>volumeTh4); endPoint1=frame2sampleIndex([index1(1), index1(end)], frameSize, overlap); endPoint2=frame2sampleIndex([index2(1), index2(end)], frameSize, overlap); endPoint3=frame2sampleIndex([index3(1), index3(end)], frameSize, overlap); endPoint4=frame2sampleIndex([index4(1), index4(end)], frameSize, overlap); subplot(2,1,1); time=(1:length(wave))/fs; plot(time, wave); ylabel('Amplitude'); title('Waveform'); axis([-inf inf -1 1]); line(time(endPoint1( 1))*[1 1], [-1, 1], 'color', 'm'); line(time(endPoint2( 1))*[1 1], [-1, 1], 'color', 'g'); line(time(endPoint3( 1))*[1 1], [-1, 1], 'color', 'k'); line(time(endPoint4( 1))*[1 1], [-1, 1], 'color', 'r'); line(time(endPoint1(end))*[1 1], [-1, 1], 'color', 'm'); line(time(endPoint2(end))*[1 1], [-1, 1], 'color', 'g'); line(time(endPoint3(end))*[1 1], [-1, 1], 'color', 'k'); line(time(endPoint4(end))*[1 1], [-1, 1], 'color', 'r'); legend('Waveform', 'Boundaries by threshold 1', 'Boundaries by threshold 2', 'Boundaries by threshold 3', 'Boundaries by threshold 4'); subplot(2,1,2); frameTime=frame2sampleIndex(1:frameNum, frameSize, overlap); plot(frameTime, volume, '.-'); ylabel('Sum of Abs.'); title('Volume'); axis tight; line([min(frameTime), max(frameTime)], volumeTh1*[1 1], 'color', 'm'); line([min(frameTime), max(frameTime)], volumeTh2*[1 1], 'color', 'g'); line([min(frameTime), max(frameTime)], volumeTh3*[1 1], 'color', 'k'); line([min(frameTime), max(frameTime)], volumeTh4*[1 1], 'color', 'r'); legend('Volume', 'Threshold 1', 'Threshold 2', 'Threshold 3', 'Threshold 4');

\end{verbatim}


In the above example, we have used four methods to compute the volume thresholds. These four methods all have their weakness, as explained next:

   1. A ratio times the maximal volume: Not reliable if there is an impulse in volume due to plosive sounds.
   2. A ratio times the median of the volume: Not reliable when silence occupy more than half of the audio signals.
   3. The minimal volume times a constant: This could go wrong is the noise if too big. Moreover, it is likely for some recordings to have a frame of zero volume.
   4. The volume of the first frame times a constant: This could go wrong if the first frame of the recording is unstable, which is not rare in practice. 

The ratios or constants in the above four methods should be determined through labeled training data. It should be noted wave files of different characteristics (recordings via uni-directional or omni-directional microphones, different sample rates, different bit resolutions, different frame sizes and overlaps) will have a different best thresholds.

Of course, you also create a new threshold by using linear combinations of these thresholds, etc.

From the above example, it is obvious that the leading unvoiced sound is likely to be misclassified as silence. Moreover, a single threshold might not perform well if the volume varies a lot. As a result, an improved method can be stated next:

   1. Use a upper threshold tu to determine the inital end-points.
   2. Extend the boundaries until they reach the lower threshold tl.
   3. Extend the boundaries further until they reach the ZCR threshold tzc. 

This method is illustrated as follows. 

FIGURA

The above improved method uses only three thresholds, hence it is possible to use grid search to find the best values via a set of labeled training data. 


If we apply the above method for EPD of sunday.wav, the result can plotted as follows:

Example 2Input file endPointDetection/epdVolZcr01.mwaveFile='sunday.wav'; plotOpt = 1; [y, fs, nbits] = wavReadInt(waveFile); endPoint = epdByVolZcr(y, fs, nbits, [], plotOpt);


In the above plot, the red and green lines indicates the beginning and end of sound, respectively. This example uses the function endPointDetect.m in the Audio Processing Toolbox, which use volume and ZCR as mentioned above for EPD.

Now it should be obvious that the most difficult part in EPD is to distinguish unvoiced sounds from silence reilably. One way to achieve this goal is to use high-order difference of the waveform as a time-domain features. For instance, in the following example, we use order-1, 2, 3 difference on the waveform of beautifulSundays.wav:

Example 3Input file endPointDetection/highOrderDiff01.mwaveFile='sunday.wav'; [wave, fs, nbits] = wavread(waveFile); frameSize = 256; overlap = 128; wave=wave-mean(wave); % zero-mean substraction frameMat=buffer2(wave, frameSize, overlap); % frame blocking frameNum=size(frameMat, 2); % no. of frames volume=frame2volume(frameMat, 1); sumAbsDiff1=sum(abs(diff(frameMat))); sumAbsDiff2=sum(abs(diff(diff(frameMat)))); sumAbsDiff3=sum(abs(diff(diff(diff(frameMat))))); sumAbsDiff4=sum(abs(diff(diff(diff(diff(frameMat)))))); subplot(2,1,1); time=(1:length(wave))/fs; plot(time, wave); ylabel('Amplitude'); title('Waveform'); subplot(2,1,2); frameTime=frame2sampleIndex(1:frameNum, frameSize, overlap)/fs; plot(frameTime', [volume; sumAbsDiff1; sumAbsDiff2; sumAbsDiff3; sumAbsDiff4]', '.-'); legend('Volume', 'Order-1 diff', 'Order-2 diff', 'Order-3 diff', 'Order-4 diff'); xlabel('Time (sec)');


It is obvious that the high-order difference (HOD) on the waveform can let us identify the unvoiced sound more easily for this case. Therefore you can take the union of high-volume and high HOD regions to have most robust of EPD. 


From the above example, a possible simple way of combining volume and HOD for EPD can be stated as follows:

   1. Compute volume (VOL) and the absolute sum of order-n difference (HOD).
   2. Select a weighting factor w within [0, 1] to compute a new curve VH = w*VOL + (1-w)*HOD.
   3. Find a ratio r to compute the threshold t of VH to determine the end-points. The threshold is equal to VHmin+(VHmax-VHmin)*r. 

The above method involves three parameters to be determined: n, w, r. Typical values of these parameters are n = 4, w = 0.5, and r = 0.125. However, these values vary with data sets. It is always adviceable to have these values tuned by using the target data set for a more robust result. 

